package com.cw.base.jeeyc.biz.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cw.base.jeeyc.biz.converter.ApiDatabaseConverter;
import com.cw.base.common.model.util.CacheKeyUtil;
import com.cw.base.jeeyc.biz.converter.DeployDictItemConverter;
import com.cw.base.jeeyc.biz.intf.DeployDictItemQueryBiz;
import com.cw.base.jeeyc.dao.mapper.DeployDictItemMapper;
import com.cw.base.jeeyc.dao.model.DeployDictItemDo;
import com.cw.base.jeeyc.deploy.dto.DeployDictItemDto;
import com.cw.base.jeeyc.deploy.dto.response.BatchDictItemQueryRespDto;
import com.cw.lang.cache.Cache;
import com.cw.lang.common.utils.CollectionUtil;
import com.cw.lang.common.utils.GsonUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 数据字典项接口业务实现类
 *
 * @author chenw
 * @date 2019-08-26 21:21:57
 */
@Service
@Slf4j
public class DeployDictItemQueryBizImpl extends ServiceImpl<DeployDictItemMapper, DeployDictItemDo>
    implements DeployDictItemQueryBiz {
    /**
     * 数据字典项缓存时间,单位秒
     */
    private final static int DICT_ITEM_CACHE_TIME = 24 * 60 * 60;
    @Autowired
    private DeployDictItemMapper deployDictItemMapper;
    @Autowired
    private Cache<String, ArrayList<DeployDictItemDto>> itemCache;

    /**
     * 分页查询数据字典项
     *
     * @param request 条件
     * @return PageInfo<DeployDictItemDto>
     */
    @Override
    public Page<DeployDictItemDto> selectPage(DeployDictItemDto request) {
        Page page = getBaseMapper().selectPage(new Page<>(request.getPageNum(), request.getPageSize()),
            DeployDictItemConverter.buildWrapper(request));
        page.setRecords(ApiDatabaseConverter.doList2DtoList(page.getRecords()));
        return page;
    }

    /**
     * 查询数据字典项详情信息
     *
     * @param request 条件
     * @return DeployDictItemDto
     */
    @Override
    public DeployDictItemDto queryDetail(DeployDictItemDto request) {
        if (request == null) {
            return null;
        }
        return DeployDictItemConverter.do2Dto(deployDictItemMapper.selectById(DeployDictItemDo.builder()
            .dictKey(request.getDictKey())
            .itemKey(request.getItemKey())
            .build()));
    }

    /**
     * 根据条件查询数据字典项
     *
     * @param request 条件
     * @return List<DeployDictItemDto>
     */
    @Override
    public List<DeployDictItemDto> queryList(DeployDictItemDto request) {
        if (request == null) {
            return null;
        }
        return DeployDictItemConverter.doList2DtoList(
            deployDictItemMapper.selectList(DeployDictItemConverter.buildWrapper(request)));
    }

    /**
     * 根据key查询数据字典项
     *
     * @param dictKey
     * @param itemKey
     * @return
     */
    @Override
    public DeployDictItemDto selectByKey(String dictKey, String itemKey) {

        return DeployDictItemConverter.do2Dto(deployDictItemMapper.selectById(DeployDictItemDo.builder()
            .dictKey(dictKey)
            .itemKey(itemKey)
            .build()));
    }

    /**
     * 批量查询数据字典项
     *
     * @param request
     * @return
     */
    @Override
    public BatchDictItemQueryRespDto batchQueryDictItem(DeployDictItemDto request) {
        if (CollectionUtil.isEmpty(request.getDictKeys())) {
            return null;
        }
        Map<String, List<DeployDictItemDto>> itemMap = new HashMap<>();
        List<String> needQueryDictKeys = new ArrayList<>();

        // 读取缓存,筛选出需要查数据库的dictKey
        request.getDictKeys()
            .forEach(dictKey -> {
                List<DeployDictItemDto> cacheValue = readDictItemCacheValue(dictKey);
                if (cacheValue != null) {
                    itemMap.put(dictKey, cacheValue);
                } else {
                    needQueryDictKeys.add(dictKey);
                }
            });

        // 不需要查数据库直接返回
        if (CollectionUtil.isEmpty(needQueryDictKeys)) {
            return BatchDictItemQueryRespDto.builder()
                .dictItemMap(itemMap)
                .build();
        }
        List<DeployDictItemDto> dictItemList = DeployDictItemConverter.doList2DtoList(deployDictItemMapper.selectList(
            DeployDictItemConverter.buildWrapper(DeployDictItemDto.builder()
                .dictKeys(needQueryDictKeys)
                .build())));
        if (CollectionUtil.isNotEmpty(dictItemList)) {
            Map<String, List<DeployDictItemDto>> dictItemQueryMap = dictItemList.stream()
                .collect(Collectors.groupingBy(DeployDictItemDto::getDictKey, Collectors.toList()));
            itemMap.putAll(dictItemQueryMap);
            // 缓存
            dictItemQueryMap.forEach(this::setDictItemCacheValue);
        }
        return BatchDictItemQueryRespDto.builder()
            .dictItemMap(itemMap)
            .build();
    }

    /**
     * 读取数据字典项缓存
     *
     * @param dictKey 数据字典key
     * @return List
     */
    private List<DeployDictItemDto> readDictItemCacheValue(String dictKey) {
        String cacheKey = CacheKeyUtil.getDictCacheKey(dictKey);
        List<DeployDictItemDto> cacheValue = itemCache.get(cacheKey);
        if (cacheValue != null) {
            log.info("读取数据字典[{}]缓存:{}", dictKey, GsonUtil.obj2Json(cacheValue));
        }
        return cacheValue;
    }

    /**
     * 缓存数据字典项
     *
     * @param dictKey 数据字典key
     * @param dtoList 数据字典项值
     */
    private void setDictItemCacheValue(String dictKey, List<DeployDictItemDto> dtoList) {
        String cacheKey = CacheKeyUtil.getDictCacheKey(dictKey);
        itemCache.set(cacheKey, new ArrayList<>(dtoList), DICT_ITEM_CACHE_TIME);
    }
}
